<?php
/**
 * BaseModel
 * @copyright (c) 2011-2020, Hangzhou DOJI Tech Co., Ltd.
 * This is NOT a freeware, use is subject to license terms.
 * @package BaseRepository.php
 * @link https://www.tingjunapp.com/
 * @author wujun@lanqb.cn
 * @: BaseModel.php 310000 2020-11-06 15:07:29 $
 * */

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
 * Class BaseModel
 *
 * @method static \Illuminate\Database\Eloquent\Builder select($columns = ['*'])
 * @method static \Illuminate\Database\Eloquent\Builder where($column, $operator = null, $value = null, $boolean = 'and')
 * @package App\Models
 * @method static \Illuminate\Database\Eloquent\Builder|BaseModel newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|BaseModel newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|BaseModel query()
 * @mixin \Eloquent
 */
class BaseModel extends Model
{
    use HasFactory;

    /** @var string table alias suffix */
    const ALIAS_SUFFIX = '_ext';

    /**
     * get builder instance
     * [!] 如果有分表，id为必传
     * @param string $id table primary key
     * @param bool $attach add id condition
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getInstance($id = '', $attach = true)
    {
        $query = self::query();
        $id && $query = self::setTableNameById($id, $attach);
        return $query;
    }

    /**
     * get table name by id
     * [!] 计算 $id 的32位 CRC（循环冗余校验）值，得到真实分表名
     * @param string|integer $id primary key
     * @return string
     */
    public static function getTableNameById($id)
    {
        $model = new static();
        $tableCount = Info::getInstance()->where(['key' => 'table_count'])->value('value');
        return $model->getTable() . sprintf('%u', crc32($id)) % $tableCount;
    }

    /**
     * set table name by id
     * [!] 根据 $id 值重新更新表名为分表名
     * @param string|integer $id primary key
     * @param bool $attach add id condition
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function setTableNameById($id, $attach = true)
    {
        $model = new static();
        $tableName = self::getTableNameById($id);
        $model = $model->setTable($tableName);
        $attach && $model = $model->where($model->primaryKey, $id);
        return $model->newQuery();
    }

    /**
     * get table name
     * @param mixed $id primary key
     * @return string
     */
    public static function tableName($id = '')
    {
        $model = new static();
        if ($id) {
            return self::getTableNameById($id);
        }
        return $model->getTable();
    }

    /**
     * set table name
     * @param $tableName
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function setTableName($tableName)
    {
        $model = new static();
        $model = $model->setTable($tableName);
        return $model->newQuery();
    }

    /**
     * get alias name
     * @param array $columnAry
     * @param string $alias
     * @return array
     */
    public static function getAliasName($columnAry, $alias = '')
    {
        if (empty($alias)) {
            $model = new static();
            $alias = $model->getTable();
        }
        foreach ($columnAry as &$col) {
            $col = $alias . '.' . $col;
        }
        return $columnAry;
    }

}
